package com.s7.compat;

import android.content.Intent;
import android.os.Bundle;

import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;

import java.util.List;

public abstract class CompatFragment extends Fragment {

    protected String LOG_TAG = this.getClass().getSimpleName();

    private boolean isViewCreated = false;
    private boolean isVisibleToUser = false;
    private boolean isDataLoaded = false;
    private boolean isHidden = true;
    private boolean isResume = true;

    private boolean isVisible = false;

    protected void loadData() {
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        this.isVisibleToUser = isVisibleToUser;
        isResume = false;
        tryLoadData();
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        isViewCreated = true;
        isResume = false;
        if (!isVisible) {
            tryLoadData();
        }
        isVisible = false;
    }

    @Override
    public void onResume() {
        super.onResume();
        if (isResume) {
            tryLoadData();
        }
        isResume = true;
    }

    @Override
    public void onStop() {
        super.onStop();
        isVisible = false;
    }

    @Override
    public void onDestroy() {
        isViewCreated = false;
        isVisibleToUser = false;
        isDataLoaded = false;
        isHidden = true;
        super.onDestroy();
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        isHidden = hidden;
        if (!hidden) {
            childLoadData();
        }
    }

    public void tryLoadData() {
        if (isViewCreated && isVisibleToUser && isParentVisible() && (isNeedReload() || !isDataLoaded)) {
            loadData();
            isDataLoaded = true;
            isVisible = true;
            dispatchParentVisibleState();
        }
    }

    public void childLoadData() {
        if (!isParentHidden() && (isNeedReload() || !isDataLoaded)) {
            loadData();
            isDataLoaded = true;
            dispatchParentHiddenState();
        }
    }

    public boolean isObvious() {
        return isViewCreated && isVisibleToUser && isParentVisible();
    }

    public boolean isParentVisible() {
        Fragment fragment = getParentFragment();
        return fragment == null || (fragment instanceof CompatFragment
                && ((CompatFragment) fragment).isVisibleToUser);
    }

    public void dispatchParentVisibleState() {
        FragmentManager fragmentManager = getChildFragmentManager();
        List<Fragment> fragments = fragmentManager.getFragments();
        if (fragments.isEmpty()) {
            return;
        }
        for (Fragment child : fragments) {
            if (child instanceof CompatFragment && ((CompatFragment) child).isVisibleToUser) {
                ((CompatFragment) child).tryLoadData();
            }
        }
    }

    protected boolean isNeedReload() {
        return false;
    }

    public void dispatchParentHiddenState() {
        FragmentManager fragmentManager = getChildFragmentManager();
        List<Fragment> fragments = fragmentManager.getFragments();
        if (fragments.isEmpty()) {
            return;
        }
        for (Fragment child : fragments) {
            if (child instanceof CompatFragment && !((CompatFragment) child).isHidden) {
                ((CompatFragment) child).childLoadData();
            }
        }
    }

    public boolean isParentHidden() {
        Fragment fragment = getParentFragment();
        if (fragment == null) {
            return false;
        } else if (fragment instanceof CompatFragment && !((CompatFragment) fragment).isHidden) {
            return false;
        }
        return true;
    }

    protected void startActivity(Class<?> cls) {
        Intent intent = new Intent();
        intent.setClass(getActivity(), cls);
        startActivity(intent);
    }

    protected void startActivity(Class<?> cls, Bundle bundle) {
        Intent intent = new Intent();
        intent.setClass(getActivity(), cls);
        if (bundle != null) {
            intent.putExtra("bundle", bundle);
        }
        startActivity(intent);
    }

    protected void startActivity(Class<?> cls, int sign) {
        Intent intent = new Intent();
        intent.setClass(getActivity(), cls);
        startActivityForResult(intent, sign);
    }


    protected void startActivity(Class<?> cls, int sign, Bundle bundle) {
        Intent intent = new Intent();
        intent.setClass(getActivity(), cls);
        if (bundle != null) {
            intent.putExtra("bundle", bundle);
        }
        startActivityForResult(intent, sign);
    }

}
